home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-19
/
iritsm3s.zip
/
COLORTBL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-08
|
9KB
|
216 lines
/*****************************************************************************
* Routines to prpepare the color table for the given scene. Each color *
* get equal share in the map table, so its modules does: *
* 1. Scans all objects and retrieve all possible colors. *
* 2. Create a color map table, of specified size (in GlblShadeInfo global *
* structure) and interpolate intensity levels for each color into it. *
* 3. Update the objects for their index into the color map. *
* *
* Written by: Gershon Elber Ver 2.0, Mar. 1990 *
*****************************************************************************/
#ifdef __MSDOS__
#include <stdlib.h>
#endif /* __MSDOS__ */
#include <math.h>
#include <stdio.h>
#include <time.h>
#include "program.h"
#include "iritprsr.h"
/* The colors can be specified as indices in which we must convert to RGB: */
/* We uses the EGA convension (see also TC 2.0 graphics.h file). */
static int TransColorTable[][4] = {
{ /* BLACK */ 0, 0, 0, 0 },
{ /* BLUE */ 1, 0, 0, 255 },
{ /* GREEN */ 2, 0, 255, 0 },
{ /* CYAN */ 3, 0, 255, 255 },
{ /* RED */ 4, 255, 0, 0 },
{ /* MAGENTA */ 5, 255, 0, 255 },
{ /* BROWN */ 6, 50, 0, 0 },
{ /* LIGHTGRAY */ 7, 127, 127, 127 },
{ /* DARKGRAY */ 8, 63, 63, 63 },
{ /* LIGHTBLUE */ 9, 0, 0, 255 },
{ /* LIGHTGREEN */ 10, 0, 255, 0 },
{ /* LIGHTCYAN */ 11, 0, 255, 255 },
{ /* LIGHTRED */ 12, 255, 0, 0 },
{ /* LIGHTMAGENTA */ 13, 255, 0, 255 },
{ /* YELLOW */ 14, 255, 255, 0 },
{ /* WHITE */ 15, 255, 255, 255 },
{ /* BROWN */ 20, 50, 0, 0 },
{ /* DARKGRAY */ 56, 63, 63, 63 },
{ /* LIGHTBLUE */ 57, 0, 0, 255 },
{ /* LIGHTGREEN */ 58, 0, 255, 0 },
{ /* LIGHTCYAN */ 59, 0, 255, 255 },
{ /* LIGHTRED */ 60, 255, 0, 0 },
{ /* LIGHTMAGENTA */ 61, 255, 0, 255 },
{ /* YELLOW */ 62, 255, 255, 0 },
{ /* WHITE */ 63, 255, 255, 255 },
{ -1, 0, 0, 0 }
};
static void PrepareAllObjects1(IPObjectStruct *PObjects,
GifColorType *Colors, int *NumColors);
static void InsertColor(IPObjectStruct *PObject, GifColorType *Colors,
int *NumColors);
static void PrepareAllObjects2(IPObjectStruct *PObjects, GifColorType *Colors,
int NumColors);
static void UpdateColorIndex(IPObjectStruct *PObject, GifColorType *Colors,
int NumColors);
/*****************************************************************************
* Routine to prepare color map for the given scene. *
*****************************************************************************/
void PrepareColorTable(IPObjectStruct *PObjects)
{
int i, j, NumColors = 0, NumOfObjs, ColorMapSize, Levels,
*MinIntensityIndex;
RealType DIntensity, CrntIntensity;
GifColorType *Colors, *ColorMap;
IPObjectStruct *PObject;
for (NumOfObjs = 0, PObject = PObjects; /* How many objects do we have? */
PObject != NULL;
NumOfObjs++, PObject = PObject -> Pnext);
Colors = (GifColorType *) MyMalloc(sizeof(GifColorType) * NumOfObjs);
PrepareAllObjects1(PObjects, Colors, &NumColors);
/* Allocate color table and fill it in: */
ColorMapSize = (1 << GlblShadeInfo.BitsPerPixel);
GlblShadeInfo.PColorMap = ColorMap =
(GifColorType *) MyMalloc(sizeof(GifColorType) * ColorMapSize);
GlblShadeInfo.MinIntensityIndex = MinIntensityIndex =
(int *) MyMalloc(sizeof(int) * ColorMapSize);
/* Save one place to hold the back ground color: */
if (NumColors == 0) {
fprintf(stderr, "No color allocated - that is really wierd!\n");
MyExit(1);
}
GlblShadeInfo.LevelsPerColor = Levels = (ColorMapSize - 1) / NumColors;
if (Levels == 0) {
fprintf(stderr, "Too many colors (%d) for color map size (%d), exit.\n",
NumColors, ColorMapSize);
MyExit(1);
}
/* Insert the back ground color in: */
for (i = 0; TransColorTable[i][0] >= 0; i++)
if (TransColorTable[i][0] == GlblShadeInfo.BackGroundColor) break;
if (TransColorTable[i][0] < 0) {
fprintf(stderr,
"Undefined color required (%d) for background, default selected instead.\n",
PObjects -> Color);
PObjects -> Color = GlblShadeInfo.DefaultColor;
}
ColorMap[0].Red = TransColorTable[i][1];
ColorMap[0].Green = TransColorTable[i][2];
ColorMap[0].Blue = TransColorTable[i][3];
/* O.k. time to interpolate the colors. Each given color intensities are */
/* interplated between the ambient light and full intensity (1.0): */
DIntensity = (1.0 - GlblShadeInfo.Ambient) / Levels;
for (i = 0; i < NumColors; i++) {
CrntIntensity = 1.0;
for (j = 0; j < Levels; j++) {
ColorMap[i * Levels + j + 1].Red =
(int) (Colors[i].Red * CrntIntensity);
ColorMap[i * Levels + j + 1].Green =
(int) (Colors[i].Green * CrntIntensity);
ColorMap[i * Levels + j + 1].Blue =
(int) (Colors[i].Blue * CrntIntensity);
MinIntensityIndex[i * Levels + j + 1] = (i + 1) * Levels;
CrntIntensity -= DIntensity;
}
}
/* Now the final step - let the objects know where their color is mapped */
/* to in the color table. */
PrepareAllObjects2(PObjects, Colors, NumColors);
free((char *) Colors);
}
/*****************************************************************************
* Scan all objects (first pass). *
*****************************************************************************/
static void PrepareAllObjects1(IPObjectStruct *PObjects, GifColorType *Colors,
int *NumColors)
{
while (PObjects) {
InsertColor(PObjects, Colors, NumColors);
PObjects = PObjects -> Pnext;
}
}
/*****************************************************************************
* Scanning all the object in tree PBinTree and prepare them. *
*****************************************************************************/
static void InsertColor(IPObjectStruct *PObject, GifColorType *Colors,
int *NumColors)
{
int i;
if (PObject -> Color != RGB_COLOR_GIVEN) {
/* Translate the color into RGB form: */
for (i = 0; TransColorTable[i][0] >= 0; i++)
if (TransColorTable[i][0] == PObject -> Color) break;
if (TransColorTable[i][0] < 0) {
fprintf(stderr,
"Undefined color required (%d), default selected instead.\n",
PObject -> Color);
PObject -> Color = GlblShadeInfo.DefaultColor;
}
PObject -> RGB[0] = TransColorTable[i][1];
PObject -> RGB[1] = TransColorTable[i][2];
PObject -> RGB[2] = TransColorTable[i][3];
}
/* Lets see if this color exists in table already, and if so do nothing: */
for (i = 0; i < *NumColors; i++)
if (PObject -> RGB[0] == Colors[i].Red &&
PObject -> RGB[1] == Colors[i].Green &&
PObject -> RGB[2] == Colors[i].Blue) return;
/* Its a new color - add it to out colors table to allocate: */
Colors[*NumColors].Red = PObject -> RGB[0];
Colors[*NumColors].Green = PObject -> RGB[1];
Colors[(*NumColors)++].Blue = PObject -> RGB[2];
}
/*****************************************************************************
* Scan all objects (second pass). *
*****************************************************************************/
static void PrepareAllObjects2(IPObjectStruct *PObjects,
GifColorType *Colors, int NumColors)
{
while (PObjects) {
UpdateColorIndex(PObjects, Colors, NumColors);
PObjects = PObjects -> Pnext;
}
}
/*****************************************************************************
* Update object with the index to its color in the color map. *
*****************************************************************************/
static void UpdateColorIndex(IPObjectStruct *PObject, GifColorType *Colors,
int NumColors)
{
int i;
/* Find this color in table (must be in it...): */
for (i = 0; i < NumColors; i++)
if (PObject -> RGB[0] == Colors[i].Red &&
PObject -> RGB[1] == Colors[i].Green &&
PObject -> RGB[2] == Colors[i].Blue) break;
/* Color table hold this object color, with decreasing intensity, from */
/* this index up to (i + 1) * GlblShadeInfo.LevelsPerColor. */
PObject -> Color = i * GlblShadeInfo.LevelsPerColor + 1;
}